/**
 * @(#)ApkConfigController.java 2016年12月1日
 * Copyright(C) 2016 ZHEXIN IT CO.,LTD. All rights reserved.
 */
package org.jsbd.boss.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.jsbd.boss.common.DataGridModel;
import org.jsbd.boss.common.ResponseUtils;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.domian.channel.ChannelApkConfig;
import org.jsbd.boss.domian.channel.ChannelApkConfigDto;
import org.jsbd.boss.domian.channel.ChannelScriptItem;
import org.jsbd.boss.domian.channel.ChannelScriptRepo;
import org.jsbd.boss.domian.channel.ChannelScriptRepoMark;
import org.jsbd.boss.domian.channel.ClientRunInfo;
import org.jsbd.boss.service.IApkTaskQueryService;
import org.jsbd.boss.service.IChannelApkInfoService;
import org.jsbd.boss.service.IScriptService;
import org.jsbd.boss.util.CacheKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

/**
 * 脚本库
 * 
 * @author <a href="mailto:wangjunbiao@zhexinit.com" >王俊标</a>
 * @version 1.0.0
 */
@Controller
@RequestMapping("/script")
public class ScriptController {
	public static final Logger LOGGER = LoggerFactory.getLogger(ScriptController.class);

	@Resource
	private IScriptService scriptService;
	@Resource
	private RedisClient redisClient;
	@Resource
	private IChannelApkInfoService channelApkService;
	@Resource
	private IApkTaskQueryService apkTaskQueryService;

	/**
	 * 脚本库页面
	 * 
	 * @return 脚本库页面
	 */
	@RequestMapping(value = "scriptRepoList")
	public String list() {
		return "/script/scriptRepoList";
	}

	/**
	 * 脚本库数据
	 * 
	 * @param page 分页信息
	 * @param channelScriptRepo 查询信息
	 * @return 脚本库数据
	 */
	@RequestMapping(value = "scriptRepoListJson")
	@ResponseBody
	public Map<String, Object> scriptRepoListJson(DataGridModel page, ChannelScriptRepo channelScriptRepo) {
		Map<String, Object> map = scriptService.getScriptRepoListJson(page, channelScriptRepo);
		return map;
	}
	
	/**
	 * 新增脚本库页面
	 * 
	 * @return 新增脚本库页面
	 */
	@RequestMapping(value = "addScriptRepo", method = RequestMethod.GET)
	public String addScriptRepo() {
		return "/script/addScriptRepo";
	}
	
	/**
	 * 新增脚本库
	 * 
	 * @param channelScriptRepo 脚本库实体
	 * @param response 
	 */
	@RequestMapping(value = "addScriptRepo", method = RequestMethod.POST)
	public void addScriptRepo(ChannelScriptRepo channelScriptRepo, HttpServletResponse response) {
		try {
			String name = channelScriptRepo.getName();
			ChannelScriptRepo csr = scriptService.getScriptRepoByName(name);
			if (null != csr) {
				ResponseUtils.responseInfoExists(response);
			} else {
				scriptService.saveChannelScriptRepo(channelScriptRepo);
				ResponseUtils.responseSuccess(response);
			}
		} catch (Exception e) {
			LOGGER.error("保存脚本库出错", e);
			ResponseUtils.responseInfoExists(response);
		}
	}
	
	/**
	 * 编辑脚本库页面
	 * 
	 * @param id 脚本库ID
	 * @param model 
	 * @return 编辑脚本库页面
	 */
	@RequestMapping(value = "{id}/editScriptRepo", method = RequestMethod.GET)
	public String editScriptRepo(@PathVariable Long id, Model model) {
		ChannelScriptRepo csr = scriptService.getScriptRepoById(id);
		model.addAttribute("csr", csr);
		return "/script/editScriptRepo";
	}
	
	/**
	 * 编辑脚本库
	 * 
	 * @param channelScriptRepo 脚本库实体
	 * @param response 
	 */
	@RequestMapping(value = "editScriptRepo", method = RequestMethod.POST)
	public void editScriptRepo(ChannelScriptRepo channelScriptRepo, HttpServletResponse response) {
		try {
			String name = channelScriptRepo.getName();
			ChannelScriptRepo csr = scriptService.getScriptRepoByName(name);
			if (null != csr) {
				ResponseUtils.responseInfoExists(response);
			} else {
				scriptService.editChannelScriptRepo(channelScriptRepo);
				ResponseUtils.responseSuccess(response);
			}
		} catch (Exception e) {
			LOGGER.error("保存脚本库出错", e);
			ResponseUtils.responseInfoExists(response);
		}
	}
	
	/**
	 * 关联包页面
	 * 
	 * @param id 脚本库Id
	 * @param model
	 * @return 关联包页面
	 */
	@RequestMapping(value = "{id}/addMark", method = RequestMethod.GET)
	public String addMark(@PathVariable Long id, Model model) {
		ChannelScriptRepoMark csrm = new ChannelScriptRepoMark();
		csrm.setRepoId(id);
		model.addAttribute("csrm", csrm);
		return "/script/addMark";
	}
	
	/**
	 * 配置脚本执行量
	 * 
	 * @param id 脚本库Id
	 * @param model
	 * @return 配置脚本执行量
	 */
	@RequestMapping(value = "{id}/configScriptNum", method = RequestMethod.GET)
	public String configScriptNum(@PathVariable Long id, Model model) {
		ChannelScriptItem csi = new ChannelScriptItem();
		csi.setRepoId(id);
		model.addAttribute("csi", csi);
		return "/script/configScriptNum";
	}
	
	/**
	 * 获取脚本库下脚本信息
	 * 
	 * @param channelApkInfo
	 * @param repoId
	 * @return
	 */
	@RequestMapping(value = "configScriptNumListjson")
	@ResponseBody
	public Map<String, Object> configPageList(Long repoId, DataGridModel page) {
		List<ChannelScriptItem> list = scriptService.getChannelScriptItemByRepoid(repoId);
		Map<String, Object> results = new HashMap<String, Object>();
		results.put("rows", list);
		results.put("total", list.size());
		return results;
	}
	
	/**
	 * 保存脚本执行量
	 * 
	 * @param channelApkInfo
	 * @param repoId
	 * @return
	 */
	@RequestMapping(value = "saveConfigScriptNum")
	public void saveConfigScriptNum(ChannelScriptItem channelScriptItem, HttpServletResponse response) {
		try {
			scriptService.saveConfigScriptNum(channelScriptItem);
			String filePath = channelScriptItem.getFilePath();
			Long repoId = channelScriptItem.getRepoId();
			List<ChannelScriptRepoMark> marks = scriptService.getMarksByRepoId(repoId);
			Integer num = channelScriptItem.getNum();
			if (null == num) {
				num = 0;
			}
			for (ChannelScriptRepoMark csrm : marks) {
				redisClient.hset(CacheKey.SCRIPT_NUM, filePath + "_" + csrm.getMark() + "_" + repoId, num);
			}
			ResponseUtils.responseSuccess(response);
		} catch (Exception e) {
			LOGGER.error("保存脚本执行量出错： " + e.getMessage());
		}
	}
	
	/**
	 * 获取包信息
	 * 
	 * @param channelApkInfo
	 * @param repoId
	 * @return
	 */
	@RequestMapping(value = "configList")
	@ResponseBody
	public Map<String, Object> configPageList(Integer isDelete, Long repoId, String mark, DataGridModel page) {
		//查询关键词
		List<String> keywords = new ArrayList<>();
		if (StringUtils.isNotBlank(mark)) {
			String[] marks = mark.split(" ");
			for (String keyword : marks) {
				keywords.add(keyword);
			}
		}
		
		//所有Apk信息
		List<ChannelApkConfigDto> list = channelApkService.getConfigApkListByIsdelete(isDelete, keywords);
		
		//已经关联了脚本库的包
		List<ChannelScriptRepoMark> csrms = scriptService.getAllMarks();
		
		//设置脚本库
		Map<String, String> marks = new HashMap<String, String>();
		for (ChannelScriptRepoMark csrm : csrms) {
			marks.put(csrm.getMark(), csrm.getName());
		}
		Set<String> keys = marks.keySet();
		List<ChannelApkConfigDto> relList = new ArrayList<ChannelApkConfigDto>();
		Iterator<ChannelApkConfigDto> it = list.iterator();
		while(it.hasNext()){
			ChannelApkConfigDto cac = it.next();
		    if (keys.contains(cac.getMark())) {
			   relList.add(cac);
			   it.remove();
		    }
		}
		if (relList.size() != 0) {
			for (ChannelApkConfigDto cac : relList) {
				cac.setRepoName(marks.get(cac.getMark()));
			}
		}
		list.addAll(0, relList);
		
		//分页
		Map<String, Object> results = new HashMap<String, Object>();
		int len = list.size();
		if(page.getCurrentRow()>=len){
			results.put("total", 0);
			results.put("rows",new ArrayList<ChannelApkConfigDto>(0));
			return results;
		}
		if(page.getCurrentRow() + page.getRows() < len){
			len = page.getCurrentRow() + page.getRows();
		}
		List<ChannelApkConfigDto> showList = list.subList(page.getCurrentRow(), len);
		results.put("rows", showList);
		results.put("total", list.size());
		
		return results;
	}
	
	/**
	 * 关联包
	 * 
	 * @param id 脚本库Id
	 * @param model
	 * @return 关联包页面
	 */
	@RequestMapping(value = "addMark", method = RequestMethod.POST)
	public void addMark(String marks, Long repoId, HttpServletResponse response) {
		try {
			String[] markArr = marks.split(",");
			
			List<String> newTaskScript = scriptService.getFilePathByRepoIdAndType(repoId, 1);
			List<String> retentTaskScript = scriptService.getFilePathByRepoIdAndType(repoId, 2);
			List<ChannelScriptRepoMark> list = new ArrayList<ChannelScriptRepoMark>();
			for (String mark : markArr) {
				ChannelScriptRepoMark csrm = new ChannelScriptRepoMark();
				csrm.setRepoId(repoId);
				csrm.setMark(mark);
				list.add(csrm);
				
				redisClient.hset(CacheKey.SCRIPT_MARK, mark + '_' + 1, newTaskScript);
				redisClient.hset(CacheKey.SCRIPT_MARK, mark + '_' + 2, retentTaskScript);
				redisClient.hset(CacheKey.SCRIPT_MARK_REPOID, mark, repoId);
			}
			scriptService.addMark(list);
			ResponseUtils.responseSuccess(response);
		} catch (Exception e) {
			LOGGER.error("保存脚本库出错", e);
			ResponseUtils.responseFailure(response);
		}
	}
	
	/**
	 * 删除关联包
	 * 
	 * @param mark mark
	 * @param response 
	 */
	@RequestMapping(value = "delMark", method = RequestMethod.POST)
	public void delMark(String marks, HttpServletResponse response) {
		try {
			String[] markArr = marks.split(",");
			
			for (String mark : markArr) {
				Long repoId = (Long) redisClient.hget(CacheKey.SCRIPT_MARK_REPOID, mark);
				
				redisClient.hdel(CacheKey.SCRIPT_MARK, mark + '_' + 1);
				redisClient.hdel(CacheKey.SCRIPT_MARK, mark + '_' + 2);
				redisClient.hdel(CacheKey.SCRIPT_MARK_REPOID, mark);
				List<String> filePaths = scriptService.getFilePathByRepoId(repoId);
				for (String filePath : filePaths) {
					redisClient.hdel(CacheKey.SCRIPT_NUM, filePath + "_" + mark + "_" + repoId);
				}
				scriptService.deleteByMark(mark);
			}
			
			ResponseUtils.responseSuccess(response);
		} catch (Exception e) {
			LOGGER.error("删除脚本库关联包出错", e);
			ResponseUtils.responseInfoExists(response);
		}
	}
	
	/**
	 * 脚本页面
	 * 
	 * @return 脚本页面
	 */
	@RequestMapping(value = "scriptItemList")
	public String scriptList() {
		return "/script/scriptItemList";
	}

	/**
	 * 脚本数据
	 * 
	 * @param page 分页信息
	 * @param channelScriptRepo 查询信息
	 * @return 脚本库数据
	 */
	@RequestMapping(value = "scriptItemListJson")
	@ResponseBody
	public Map<String, Object> scriptItemListJson(DataGridModel page, ChannelScriptItem channelScriptItem) {
		Map<String, Object> map = scriptService.getScriptListJson(page, channelScriptItem);
		return map;
	}
	
	/**
	 * 新增脚本页面
	 * 
	 * @return 新增脚本页面
	 */
	@RequestMapping(value = "addScriptItem", method = RequestMethod.GET)
	public String addScript() {
		return "/script/addScriptItem";
	}
	
	/**
	 * 获取脚本库列表
	 * 
	 * @param isEnable 是否启用
	 * @return 返回脚本库列表
	 */
	@RequestMapping(value = "scriptRepoData", method = RequestMethod.GET)
	@ResponseBody
	public List<ChannelScriptRepo> scriptRepoData (Integer isEnable) {
		return scriptService.getScriptRepoByEnable(isEnable);
	}
	
	
	/**
	 * 新增脚本
	 * 
	 * @param channelScript 脚本库实体
	 * @param response 
	 */
	@RequestMapping(value = "addScriptItem", method = RequestMethod.POST)
	public void addScriptItem(ChannelScriptItem channelScriptItem, MultipartFile file, HttpServletResponse response) {
		try {
			Integer type = channelScriptItem.getType();
			if (type == -1 ) {
				ResponseUtils.responseValidation(response, "请选择脚本类型!");
			}
			
			String name = channelScriptItem.getName();
			ChannelScriptItem csi = scriptService.getScriptItemByName(name);
			if (null != csi) {
				ResponseUtils.responseInfoExists(response);
			} else {
				scriptService.saveChannelScriptItem(channelScriptItem, file);
				ResponseUtils.responseSuccess(response);
			}
		} catch (Exception e) {
			LOGGER.error("保存脚本库出错", e);
			ResponseUtils.responseInfoExists(response);
		}
	}
	
	/**
	 * 废弃脚本
	 * 
	 * @param name 脚本名称
	 * @param response 
	 */
	@RequestMapping(value = "abandon", method = RequestMethod.GET)
	public void abandon(String name, HttpServletResponse response) {
		try {
			scriptService.abandonScript(name);
			ResponseUtils.responseSuccess(response);
		} catch (Exception e) {
			LOGGER.error("废弃脚本出错", e);
			ResponseUtils.responseFailure(response);
		}
	}
	
	@RequestMapping(value = "/randomScript")
	@ResponseBody
	public Map<String, Object> randomScript(String mark, Integer type, HttpServletResponse response) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("filePath", scriptService.randomScript(mark, type));
		return map;
	}

}
